package cn.bdqn.controller;

import cn.bdqn.dto.Dto;
import cn.bdqn.pojo.ItripHotelOrder;
import cn.bdqn.service.OrderService;
import cn.bdqn.wx.WXPayConstants;
import cn.bdqn.wx.WXPayRequest;
import cn.bdqn.wx.WXPayUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 2018/8/29
 */
@Controller
public class WXPaymentController {

    @Resource
    private OrderService orderService;


    /**
     * 生成二维码
     *
     * @param orderNo
     * @return
     */
    @RequestMapping(value = "/createCode/{orderNo}", method = RequestMethod.GET)
    @ResponseBody
    public Dto createCode(@PathVariable String orderNo) {

        Dto dto = new Dto();

        HashMap<String, String> data = new HashMap<String, String>();
        //1构造参数
        try {
            ItripHotelOrder itripHotelOrder = orderService.loadItripHotelOrder(orderNo);

            data.put("body", "爱旅行项目订单支付");
            data.put("out_trade_no", orderNo);
            data.put("device_info", "");
            data.put("fee_type", "CNY");
            //订单金额 以分为单位
            data.put("total_fee", itripHotelOrder.getPayAmount().multiply(new BigDecimal(100)).toBigInteger().toString());
            data.put("spbill_create_ip", "123.12.12.123");
            data.put("notify_url", "http://test.letiantian.me/wxpay/notify");
            data.put("trade_type", "NATIVE");
            data.put("product_id", "12");
            data.put("appid", "wxab8acb865bb1637e");
            data.put("mch_id", "11473623");
            data.put("Sign_type", "HMAC-SHA256");
            data.put("nonce_str", WXPayUtil.generateNonceStr());

            //2转成xml请求微信支付平台

            String reqXml = WXPayUtil.generateSignedXml(data, "2ab9071b06b9f739b950ddb41db2690d", WXPayConstants.SignType.HMACSHA256);
            //3.请求微信支付平台  获取 预支付链接
            String respXml = WXPayRequest.requestWx("https://api.mch.weixin.qq.com/pay/unifiedorder", reqXml);

            Map<String, String> resultMap = WXPayUtil.xmlToMap(respXml);
            if (resultMap.get("return_code").equals("SUCCESS") && resultMap.get("result_code").equals("SUCCESS")) {
                Map<String, String> result = new HashMap<String, String>();
                result.put("code_url", resultMap.get("code_url"));
                dto.setData(result);
                dto.setCode("0000");
                dto.setSuccess("true");
                return dto;

            } else {
                dto.setData(resultMap.get("return_msg"));
                dto.setCode("10086");
                dto.setSuccess("false");
                return dto;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }


        //3获取code_url 返回给前端
        dto.setCode("10086");
        dto.setMsg("发生错误");

        return dto;
    }

    /**
     * 接收微信的通知
     */
    @RequestMapping(value = "/notify",method = RequestMethod.POST)
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) {
        //1.从request获取xml流 转化成 map数据
        try {
            StringBuffer stringBuffer = new StringBuffer();
            InputStream inputStream = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            String temp;
            while (null != (temp = reader.readLine())) {
                stringBuffer.append(temp);
            }
            reader.close();
            inputStream.close();
            Map<String, String> resultMap = WXPayUtil.xmlToMap(stringBuffer.toString());
            boolean flag = WXPayUtil.isSignatureValid(resultMap, "2ab9071b06b9f739b950ddb41db2690d", WXPayConstants.SignType.HMACSHA256);
            if (flag) {
                if (resultMap.get("return_code").equals("SUCCESS") && resultMap.get("result_code").equals("SUCCESS")) {
                    Map<String, String> result = new HashMap<String, String>();
                    result.put("code_url", resultMap.get("code_url"));
                    //获取订单号
                    String out_trade_no=resultMap.get("out_trade_no");
                    String trade_no=resultMap.get("prepay_id");
                 if (! orderService.processed(out_trade_no)){
                     orderService.paySuccess(out_trade_no,2,trade_no);
                 }

                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //3.给微信返回结果
            Map<String,String> returnMap=new HashMap<String,String>();
            returnMap.put("return_code","SUCCESS");
            returnMap.put("return_msg","SUCCESS");
            String respXml= null;
            try {
                respXml = WXPayUtil.generateSignedXml(returnMap,"2ab9071b06b9f739b950ddb41db2690d",WXPayConstants.SignType.MD5);
                response.getWriter().write(respXml);
                response.getWriter().flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 刷新订单
     * @param orderNo
     * @return
     */
    @RequestMapping(value = "/queryorderstatus/{orderNo}", method = RequestMethod.GET)
    @ResponseBody
    public Dto queryOrderStatus(@PathVariable String orderNo){
        Dto dto =new Dto();
        try {
            ItripHotelOrder itripHotelOrder= orderService.loadItripHotelOrder(orderNo);
            dto.setData(itripHotelOrder);
            dto.setMsg("返回订单状态成功");
            dto.setCode("0000");
            return dto;
        } catch (Exception e) {
            e.printStackTrace();
        }
        dto.setMsg("查询失败");
        dto.setCode("10086");
        return dto;
    }
}
